package com.relytosoft.mizar.analyze.structure.services.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.kafka.producer.KafkaOpMsg;
import com.relytosoft.dubhe.common.kafka.producer.KafkaProducer;
import com.relytosoft.mizar.analyze.base.constant.MediaMqConstants;
import com.relytosoft.mizar.analyze.base.entity.pojo.dto.TaskRequestDto;
import com.relytosoft.mizar.analyze.base.enums.DeleteStatusEnum;
import com.relytosoft.mizar.analyze.base.enums.TaskStatusEnum;
import com.relytosoft.mizar.analyze.structure.api.entity.AyStructureTask;
import com.relytosoft.mizar.analyze.structure.api.entity.AyStructureTaskSon;
import com.relytosoft.mizar.analyze.structure.api.pojo.dto.AyTaskIdDto;
import com.relytosoft.mizar.analyze.structure.api.pojo.query.AyStructureTaskSonQuery;
import com.relytosoft.mizar.analyze.structure.services.mapper.AyStructureTaskSonMapper;
import com.relytosoft.mizar.analyze.structure.services.service.AyStructureTaskService;
import com.relytosoft.mizar.analyze.structure.services.service.AyStructureTaskSonService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author: zyc
 * @version: v1.0
 * @description: com.relytosoft.mizar.analyze.structure.services.service.impl
 * @Date: 2022/5/13 9:48
 */
@Service
public class AyStructureTaskSonServiceImpl extends ServiceImpl<AyStructureTaskSonMapper, AyStructureTaskSon> implements AyStructureTaskSonService {

    @Resource
    private AyStructureTaskSonMapper ayStructureTaskSonMapper;

    @Resource
    private KafkaProducer kafkaProducer;

    @Resource
    private AyStructureTaskService ayStructureTaskService;

    @Override
    public IPage<AyStructureTaskSon> selectAyStructureTaskSonPageList(PageQuery pageQuery, AyStructureTaskSonQuery ayStructureTaskSonQuery) {
        if (StrUtil.isBlank(pageQuery.getOrderByColumn())) {
            pageQuery.setOrderByColumn("id");
            pageQuery.setIsAsc("desc");
        }
        return ayStructureTaskSonMapper.selectPageTaskSonList(pageQuery.build(), ayStructureTaskSonQuery);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean insertAyStructureTaskSon(AyStructureTaskSon ayStructureTaskSon) {
        Integer isDeleted = ayStructureTaskSonMapper.selectTaskSonById(ayStructureTaskSon.getCameraId());
        if (null != isDeleted) {
            throw new ServiceException("该通道已存在未删除的子任务");
        } else {
            boolean save = this.save(ayStructureTaskSon);
            return save;
        }
    }

    @Override
    public boolean updateAyStructureTaskSon(AyTaskIdDto ayTaskIdDto) {
        QueryWrapper<AyStructureTaskSon> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(AyStructureTaskSon::getId, ayTaskIdDto.getIds())
                .ne(AyStructureTaskSon::getStatus, TaskStatusEnum.RUNING.getValue())
                .eq(AyStructureTaskSon::getIsDeleted, DeleteStatusEnum.NOT_DELETED.getValue());
        AyStructureTaskSon ayStructureTaskSon = new AyStructureTaskSon();
        ayStructureTaskSon.setIsDeleted(DeleteStatusEnum.DELETED.getValue());
        ayStructureTaskSon.setUpdatedId(ayTaskIdDto.getUpdatedId());
        ayStructureTaskSon.setUpdatedBy(ayTaskIdDto.getUpdatedBy());
        boolean update = this.update(ayStructureTaskSon, wrapper);
        return update;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean startAyStructureTaskSon(AyTaskIdDto ayTaskIdDto, AyStructureTaskSon ayStructureTaskSon) {
        if ((TaskStatusEnum.FINISHED.getValue() == ayStructureTaskSon.getStatus())
                && DeleteStatusEnum.NOT_DELETED.getValue() == ayStructureTaskSon.getIsDeleted()) {
            ayStructureTaskSon.setIsDeleted(DeleteStatusEnum.DELETED.getValue());
            ayStructureTaskSon.setUpdatedBy(ayTaskIdDto.getUpdatedBy());
            ayStructureTaskSon.setUpdatedId(ayTaskIdDto.getUpdatedId());
            this.updateById(ayStructureTaskSon);
            AyStructureTaskSon taskSon = createTaskSon(ayStructureTaskSon);
            boolean save = this.save(taskSon);
            if (save) {
                return true;
            }
        } else if (TaskStatusEnum.NOT_STARTED.getValue() == ayStructureTaskSon.getStatus()
                && DeleteStatusEnum.NOT_DELETED.getValue() == ayStructureTaskSon.getIsDeleted()) {
            ayStructureTaskSon.setStatus(TaskStatusEnum.CREATED.getValue());
            boolean update = this.updateById(ayStructureTaskSon);
            if (update) {
                return true;
            }
        }
        throw new ServiceException("不符合启动条件的结构化子任务");
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean stopAyStructureTaskSon(AyTaskIdDto ayTaskIdDto, AyStructureTaskSon ayStructureTaskSon) {
        if ((TaskStatusEnum.RUNING.getValue() == ayStructureTaskSon.getStatus())
                && DeleteStatusEnum.NOT_DELETED.getValue() == ayStructureTaskSon.getIsDeleted()) {
            ayStructureTaskSon.setStatus(TaskStatusEnum.FINISHED.getValue());
            ayStructureTaskSon.setUpdatedBy(ayTaskIdDto.getUpdatedBy());
            ayStructureTaskSon.setUpdatedId(ayTaskIdDto.getUpdatedId());
            ayStructureTaskSon.setEndTime(LocalDateTime.now());
            boolean update = this.updateById(ayStructureTaskSon);
            return update;
        }
        return false;
    }


    @Override
    public void insertStructureTaskSonKafkaOpMsg(TaskRequestDto taskRequestDto) {
        //发送新增子任务信息
        KafkaOpMsg kafkaOpMsg = new KafkaOpMsg();
        kafkaOpMsg.setOpType("insert");
        kafkaOpMsg.setData(JSONObject.toJSONString(taskRequestDto));
        kafkaProducer.send(MediaMqConstants.STRU_ANALYZE_TASK_TOPIC, JSONObject.toJSONString(kafkaOpMsg), true);
    }

    @Override
    public void deleteStructureTaskSonKafkaOpMsg(String taskId) {
        //发送需要删除子任务信息
        KafkaOpMsg kafkaOpMsg = new KafkaOpMsg();
        kafkaOpMsg.setData(taskId);
        kafkaOpMsg.setOpType("delete");
        kafkaProducer.send(MediaMqConstants.STRU_ANALYZE_TASK_TOPIC, JSONObject.toJSONString(kafkaOpMsg), true);
    }


    @Override
    public TaskRequestDto createRequest(AyStructureTaskSon ayStructureTaskSon) {
        TaskRequestDto taskRequestDto = new TaskRequestDto();
        taskRequestDto.setId(ayStructureTaskSon.getId());
        taskRequestDto.setDeviceId(ayStructureTaskSon.getCameraId());
        taskRequestDto.setDeviceName(ayStructureTaskSon.getCameraName());
        taskRequestDto.setRtspUrl(ayStructureTaskSon.getVideoUrl());
        taskRequestDto.setTaskName(ayStructureTaskSon.getTaskName());
        return taskRequestDto;
    }

    @Override
    public AyStructureTaskSon createTaskSon(AyStructureTaskSon ayStructureTaskSon) {
        AyStructureTaskSon taskSon = new AyStructureTaskSon();
        taskSon.setStructureTaskId(ayStructureTaskSon.getStructureTaskId());
        taskSon.setTaskName(ayStructureTaskSon.getTaskName());
        taskSon.setCameraId(ayStructureTaskSon.getCameraId());
        taskSon.setCameraName(ayStructureTaskSon.getCameraName());
        taskSon.setVideoUrl(ayStructureTaskSon.getVideoUrl());
        taskSon.setStatus(TaskStatusEnum.CREATED.getValue());
        taskSon.setIsDeleted(DeleteStatusEnum.NOT_DELETED.getValue());
        return taskSon;
    }

    @Override
    public List<AyStructureTaskSon> selectByStructureTaskId(Integer id) {
        QueryWrapper<AyStructureTaskSon> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(AyStructureTaskSon::getStructureTaskId, id);
        return this.baseMapper.selectList(wrapper);
    }

    @Override
    public Integer getStructureTaskId(List<AyStructureTaskSon> ayStructureTaskSons) {
        for (int i = 0; i < ayStructureTaskSons.size(); i++) {
            if (ayStructureTaskSons.get(0).getStructureTaskId() != ayStructureTaskSons.get(i).getStructureTaskId()) {
                throw new ServiceException("传入的子任务不属于同一主任务");
            }
        }
        return ayStructureTaskSons.get(0).getStructureTaskId();
    }

    @Override
    public void updateTaskStatus(Integer structureTaskId) {
        AyStructureTask ayStructureTask = ayStructureTaskService.getById(structureTaskId);
        if (ayStructureTaskSonMapper.selectStatusList(structureTaskId).stream().allMatch(item -> item == TaskStatusEnum.FINISHED.getValue())) {
            ayStructureTask.setStatus(TaskStatusEnum.FINISHED.getValue());
        }
    }

}
